//
// File: pburg.cpp
//
// MATLAB Coder version            : 5.4
// C/C++ source code generated on  : 23-Apr-2025 16:26:18
//

// Include Files
#include "pburg.h"
#include "arburg.h"
#include "datawrap.h"
#include "fft.h"
#include "freqDomainHRV_data.h"
#include "freqDomainHRV_rtwutil.h"
#include "freqz.h"
#include "linspace.h"
#include "rt_nonfinite.h"
#include "coder_array.h"
#include <cmath>
#include <string.h>

// Function Definitions
//
// Arguments    : const ::coder::array<double, 1U> &x
//                double p
//                double varargin_1
//                double varargin_2
//                ::coder::array<double, 1U> &varargout_1
//                ::coder::array<double, 1U> &varargout_2
// Return Type  : void
//
namespace coder {
void pburg(const ::coder::array<double, 1U> &x, double p, double varargin_1,
           double varargin_2, ::coder::array<double, 1U> &varargout_1,
           ::coder::array<double, 1U> &varargout_2)
{
  array<creal_T, 2U> den;
  array<creal_T, 2U> num;
  array<creal_T, 1U> h;
  array<double, 2U> a;
  array<double, 2U> b;
  array<double, 2U> b_a;
  array<double, 1U> Sxx_unscaled;
  array<double, 1U> a__1;
  array<double, 1U> wf;
  double b_b_tmp;
  double b_tmp;
  double r;
  double v;
  int i;
  int loop_ub;
  int nx;
  arburg(x, p, a, &v);
  b_tmp = varargin_2 - varargin_2 / varargin_1;
  linspace(b_tmp, varargin_1, b);
  if (std::isnan(varargin_1) || std::isinf(varargin_1)) {
    r = rtNaN;
  } else if (varargin_1 == 0.0) {
    r = 0.0;
  } else {
    r = std::fmod(varargin_1, 2.0);
    if (r == 0.0) {
      r = 0.0;
    } else if (varargin_1 < 0.0) {
      r += 2.0;
    }
  }
  if (r == 1.0) {
    r = varargin_2 / (2.0 * varargin_1);
    b_b_tmp = (varargin_1 + 1.0) / 2.0;
    b[static_cast<int>(b_b_tmp) - 1] = varargin_2 / 2.0 - r;
    b[static_cast<int>(b_b_tmp + 1.0) - 1] = varargin_2 / 2.0 + r;
  } else {
    b[static_cast<int>(varargin_1 / 2.0 + 1.0) - 1] = varargin_2 / 2.0;
  }
  b[static_cast<int>(varargin_1) - 1] = b_tmp;
  wf.set_size(b.size(1));
  loop_ub = b.size(1);
  for (i = 0; i < loop_ub; i++) {
    wf[i] = b[i];
  }
  if (a.size(1) == 1) {
    firfreqz(1.0 / a[0], varargin_1, h);
  } else {
    nx = static_cast<int>(std::fmax(0.0, 1.0 - static_cast<double>(a.size(1))));
    b_a.set_size(1, a.size(1) + nx);
    loop_ub = a.size(1);
    for (i = 0; i < loop_ub; i++) {
      b_a[i] = a[i];
    }
    for (i = 0; i < nx; i++) {
      b_a[a.size(1)] = 0.0;
    }
    nx = static_cast<int>(std::fmax(0.0, static_cast<double>(a.size(1)) - 1.0));
    b.set_size(1, nx + 1);
    b[0] = 1.0;
    for (i = 0; i < nx; i++) {
      b[i + 1] = 0.0;
    }
    if (varargin_1 < b_a.size(1)) {
      datawrap(b, varargin_1, a);
      fft(a, num);
      datawrap(b_a, varargin_1, a);
      fft(a, den);
      if (num.size(1) == den.size(1)) {
        h.set_size(num.size(1));
        loop_ub = num.size(1);
        for (i = 0; i < loop_ub; i++) {
          double ai;
          double ar;
          double bi;
          ar = num[i].re;
          ai = num[i].im;
          b_tmp = den[i].re;
          bi = den[i].im;
          if (bi == 0.0) {
            if (ai == 0.0) {
              h[i].re = ar / b_tmp;
              h[i].im = 0.0;
            } else if (ar == 0.0) {
              h[i].re = 0.0;
              h[i].im = ai / b_tmp;
            } else {
              h[i].re = ar / b_tmp;
              h[i].im = ai / b_tmp;
            }
          } else if (b_tmp == 0.0) {
            if (ar == 0.0) {
              h[i].re = ai / bi;
              h[i].im = 0.0;
            } else if (ai == 0.0) {
              h[i].re = 0.0;
              h[i].im = -(ar / bi);
            } else {
              h[i].re = ai / bi;
              h[i].im = -(ar / bi);
            }
          } else {
            double brm;
            brm = std::abs(b_tmp);
            r = std::abs(bi);
            if (brm > r) {
              b_b_tmp = bi / b_tmp;
              r = b_tmp + b_b_tmp * bi;
              h[i].re = (ar + b_b_tmp * ai) / r;
              h[i].im = (ai - b_b_tmp * ar) / r;
            } else if (r == brm) {
              if (b_tmp > 0.0) {
                b_b_tmp = 0.5;
              } else {
                b_b_tmp = -0.5;
              }
              if (bi > 0.0) {
                r = 0.5;
              } else {
                r = -0.5;
              }
              h[i].re = (ar * b_b_tmp + ai * r) / brm;
              h[i].im = (ai * b_b_tmp - ar * r) / brm;
            } else {
              b_b_tmp = b_tmp / bi;
              r = bi + b_b_tmp * b_tmp;
              h[i].re = (b_b_tmp * ar + ai) / r;
              h[i].im = (b_b_tmp * ai - ar) / r;
            }
          }
        }
      } else {
        binary_expand_op(h, num, den);
      }
    } else {
      fft(b, varargin_1, num);
      fft(b_a, varargin_1, den);
      if (num.size(1) == den.size(1)) {
        h.set_size(num.size(1));
        loop_ub = num.size(1);
        for (i = 0; i < loop_ub; i++) {
          double ai;
          double ar;
          double bi;
          ar = num[i].re;
          ai = num[i].im;
          b_tmp = den[i].re;
          bi = den[i].im;
          if (bi == 0.0) {
            if (ai == 0.0) {
              h[i].re = ar / b_tmp;
              h[i].im = 0.0;
            } else if (ar == 0.0) {
              h[i].re = 0.0;
              h[i].im = ai / b_tmp;
            } else {
              h[i].re = ar / b_tmp;
              h[i].im = ai / b_tmp;
            }
          } else if (b_tmp == 0.0) {
            if (ar == 0.0) {
              h[i].re = ai / bi;
              h[i].im = 0.0;
            } else if (ai == 0.0) {
              h[i].re = 0.0;
              h[i].im = -(ar / bi);
            } else {
              h[i].re = ai / bi;
              h[i].im = -(ar / bi);
            }
          } else {
            double brm;
            brm = std::abs(b_tmp);
            r = std::abs(bi);
            if (brm > r) {
              b_b_tmp = bi / b_tmp;
              r = b_tmp + b_b_tmp * bi;
              h[i].re = (ar + b_b_tmp * ai) / r;
              h[i].im = (ai - b_b_tmp * ar) / r;
            } else if (r == brm) {
              if (b_tmp > 0.0) {
                b_b_tmp = 0.5;
              } else {
                b_b_tmp = -0.5;
              }
              if (bi > 0.0) {
                r = 0.5;
              } else {
                r = -0.5;
              }
              h[i].re = (ar * b_b_tmp + ai * r) / brm;
              h[i].im = (ai * b_b_tmp - ar * r) / brm;
            } else {
              b_b_tmp = b_tmp / bi;
              r = bi + b_b_tmp * b_tmp;
              h[i].re = (b_b_tmp * ar + ai) / r;
              h[i].im = (b_b_tmp * ai - ar) / r;
            }
          }
        }
      } else {
        binary_expand_op(h, num, den);
      }
    }
  }
  if (varargin_1 < h.size(0)) {
    if (varargin_1 < 1.0) {
      loop_ub = 0;
    } else {
      loop_ub = static_cast<int>(varargin_1);
    }
    h.set_size(loop_ub);
  }
  nx = h.size(0);
  Sxx_unscaled.set_size(h.size(0));
  for (loop_ub = 0; loop_ub < nx; loop_ub++) {
    Sxx_unscaled[loop_ub] = rt_hypotd_snf(h[loop_ub].re, h[loop_ub].im);
  }
  loop_ub = Sxx_unscaled.size(0);
  for (i = 0; i < loop_ub; i++) {
    r = Sxx_unscaled[i];
    Sxx_unscaled[i] = r * r;
  }
  a__1.set_size(Sxx_unscaled.size(0));
  if (Sxx_unscaled.size(0) != 0) {
    nx = (Sxx_unscaled.size(0) != 1);
    i = Sxx_unscaled.size(0) - 1;
    for (loop_ub = 0; loop_ub <= i; loop_ub++) {
      a__1[loop_ub] = v * Sxx_unscaled[nx * loop_ub];
    }
  }
  if (std::isnan(varargin_1) || std::isinf(varargin_1)) {
    r = rtNaN;
  } else if (varargin_1 == 0.0) {
    r = 0.0;
  } else {
    r = std::fmod(varargin_1, 2.0);
    if (r == 0.0) {
      r = 0.0;
    } else if (varargin_1 < 0.0) {
      r += 2.0;
    }
  }
  if (r == 1.0) {
    r = (varargin_1 + 1.0) / 2.0;
    if (std::isnan(r)) {
      b.set_size(1, 1);
      b[0] = rtNaN;
    } else if (r < 1.0) {
      b.set_size(1, 0);
    } else {
      b.set_size(1, static_cast<int>(r - 1.0) + 1);
      loop_ub = static_cast<int>(r - 1.0);
      for (i = 0; i <= loop_ub; i++) {
        b[i] = static_cast<double>(i) + 1.0;
      }
    }
    Sxx_unscaled.set_size(b.size(1));
    loop_ub = b.size(1);
    for (i = 0; i < loop_ub; i++) {
      Sxx_unscaled[i] = a__1[static_cast<int>(b[i]) - 1];
    }
    if (b.size(1) < 2) {
      i = 0;
      nx = 0;
    } else {
      i = 1;
      nx = b.size(1);
    }
    loop_ub = nx - i;
    varargout_1.set_size(loop_ub + 1);
    varargout_1[0] = a__1[static_cast<int>(b[0]) - 1];
    for (nx = 0; nx < loop_ub; nx++) {
      varargout_1[nx + 1] = 2.0 * Sxx_unscaled[i + nx];
    }
  } else {
    r = varargin_1 / 2.0 + 1.0;
    if (std::isnan(r)) {
      b.set_size(1, 1);
      b[0] = rtNaN;
    } else if (r < 1.0) {
      b.set_size(1, 0);
    } else {
      b.set_size(1, static_cast<int>(r - 1.0) + 1);
      loop_ub = static_cast<int>(r - 1.0);
      for (i = 0; i <= loop_ub; i++) {
        b[i] = static_cast<double>(i) + 1.0;
      }
    }
    Sxx_unscaled.set_size(b.size(1));
    loop_ub = b.size(1);
    for (i = 0; i < loop_ub; i++) {
      Sxx_unscaled[i] = a__1[static_cast<int>(b[i]) - 1];
    }
    if (b.size(1) - 1 < 2) {
      i = 0;
      nx = 1;
    } else {
      i = 1;
      nx = b.size(1);
    }
    loop_ub = nx - i;
    varargout_1.set_size(loop_ub + 1);
    varargout_1[0] = a__1[static_cast<int>(b[0]) - 1];
    for (nx = 0; nx <= loop_ub - 2; nx++) {
      varargout_1[nx + 1] = 2.0 * Sxx_unscaled[i + nx];
    }
    varargout_1[loop_ub] = a__1[static_cast<int>(b[b.size(1) - 1]) - 1];
  }
  if (!std::isnan(varargin_2)) {
    loop_ub = varargout_1.size(0);
    for (i = 0; i < loop_ub; i++) {
      varargout_1[i] = varargout_1[i] / varargin_2;
    }
  } else {
    loop_ub = varargout_1.size(0);
    for (i = 0; i < loop_ub; i++) {
      varargout_1[i] = varargout_1[i] / 6.2831853071795862;
    }
  }
  varargout_2.set_size(b.size(1));
  loop_ub = b.size(1);
  for (i = 0; i < loop_ub; i++) {
    varargout_2[i] = wf[static_cast<int>(b[i]) - 1];
  }
}

} // namespace coder

//
// File trailer for pburg.cpp
//
// [EOF]
//
